<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
    />
    <meta
      name="description"
      content="A CZML example showing a single entity path split across multiple CZML streams."
    />
    <meta
      name="cesium-sandcastle-labels"
      content="Showcases, DataSources, CZML"
    />
    <title>Cesium Demo</title>
    <script type="text/javascript" src="../Sandcastle-header.js"></script>
    <script
      type="text/javascript"
      src="../../../Build/CesiumUnminified/Cesium.js"
      nomodule
    ></script>
    <script type="module" src="../load-cesium-es6.js"></script>
  </head>
  <body
    class="sandcastle-loading"
    data-sandcastle-bucket="bucket-requirejs.html"
  >
    <style>
      @import url(../templates/bucket.css);
    </style>
    <div id="cesiumContainer" class="fullSize"></div>
    <div id="loadingOverlay"><h1>Loading...</h1></div>
    <div id="toolbar"></div>

    <script id="cesium_sandcastle_script">
      window.startup = async function (Cesium) {
        "use strict";
        //Sandcastle_Begin
        const viewer = new Cesium.Viewer("cesiumContainer", {
          shouldAnimate: true,
        });

        const statusDisplay = document.createElement("div");
        const fuelDisplay = document.createElement("div");
        const czmlPath = "../../SampleData/";
        let vehicleEntity;

        // Add a blank CzmlDataSource to hold our multi-part entity/entities.
        const dataSource = new Cesium.CzmlDataSource();
        viewer.dataSources.add(dataSource);

        // This demo shows how a single path can be broken up into several CZML streams.
        const partsToLoad = [
          {
            url: "MultipartVehicle_part1.czml",
            range: [0, 1500],
            requested: false,
            loaded: false,
          },
          {
            url: "MultipartVehicle_part2.czml",
            range: [1500, 3000],
            requested: false,
            loaded: false,
          },
          {
            url: "MultipartVehicle_part3.czml",
            range: [3000, 4500],
            requested: false,
            loaded: false,
          },
        ];

        function updateStatusDisplay() {
          let msg = "";
          partsToLoad.forEach(function (part) {
            msg += `${part.url} - `;
            if (part.loaded) {
              msg += "Loaded.<br/>";
            } else if (part.requested) {
              msg += "Loading now...<br/>";
            } else {
              msg += "Not needed yet.<br/>";
            }
          });
          statusDisplay.innerHTML = msg;
        }

        // Helper function to mark a part as requested, and process it into the dataSource.
        function processPart(part) {
          part.requested = true;
          updateStatusDisplay();
          dataSource.process(czmlPath + part.url).then(function () {
            part.loaded = true;
            updateStatusDisplay();

            // Follow the vehicle with the camera.
            if (!viewer.trackedEntity) {
              viewer.trackedEntity = vehicleEntity = dataSource.entities.getById(
                "Vehicle"
              );
            }
          });
        }

        // Load the first part up front.
        processPart(partsToLoad[0]);

        // Load a new section before the clock naturally gets there.
        // Note this can't predict when a user may fast-forward to it.
        const preloadTimeInSeconds = 100;

        viewer.clock.onTick.addEventListener(function (clock) {
          // This example uses time offsets from the start to identify which parts need loading.
          const timeOffset = Cesium.JulianDate.secondsDifference(
            clock.currentTime,
            clock.startTime
          );

          // Filter the list of parts to just the ones that need loading right now.
          // Then, process each part that needs loading.
          partsToLoad
            .filter(function (part) {
              return (
                !part.requested &&
                timeOffset >= part.range[0] - preloadTimeInSeconds &&
                timeOffset <= part.range[1]
              );
            })
            .forEach(function (part) {
              processPart(part);
            });

          if (vehicleEntity) {
            const fuel = vehicleEntity.properties.fuel_remaining.getValue(
              clock.currentTime
            );
            if (Cesium.defined(fuel)) {
              fuelDisplay.textContent = `Fuel: ${fuel.toFixed(2)} gal`;
            }
          }
        });

        // Add a reset button, for convenience.
        Sandcastle.addToolbarButton("Reset demo", function () {
          // Put things back to the starting position.
          viewer.clock.currentTime = viewer.clock.startTime;
          viewer.clock.shouldAnimate = true;

          partsToLoad.forEach(function (part) {
            part.requested = false;
            part.loaded = false;
          });

          dataSource.entities.removeAll();
          processPart(partsToLoad[0]);
        });

        // Show the status display below the reset button.
        statusDisplay.style.background = "rgba(42, 42, 42, 0.7)";
        statusDisplay.style.padding = "5px 10px";
        document.getElementById("toolbar").appendChild(statusDisplay);

        // Show a multi-part custom property being read from CZML.
        fuelDisplay.style.background = "rgba(42, 42, 42, 0.7)";
        fuelDisplay.style.padding = "5px 10px";
        fuelDisplay.style.marginTop = "5px";
        document.getElementById("toolbar").appendChild(fuelDisplay);
        //Sandcastle_End
      };
      if (typeof Cesium !== "undefined") {
        window.startupCalled = true;
        window.startup(Cesium).catch((error) => {
          "use strict";
          console.error(error);
        });
        Sandcastle.finishedLoading();
      }
    </script>
  </body>
</html>
